package com.zxmr.hospital.customer.action;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.zxmr.action.Request;
import com.zxmr.action.RequestPayload;
import com.zxmr.action.Response;
import com.zxmr.action.ResponsePayload;
import com.zxmr.action.ResultCode;
import com.zxmr.domain.Opportunity;
import com.zxmr.domain.RelateType;
import com.zxmr.domain.Task;
import com.zxmr.domain.account.AccountType;
import com.zxmr.domain.account.User;
import com.zxmr.domain.service.OpportunityService;
import com.zxmr.domain.service.TaskSearchBean;
import com.zxmr.navigate.ExecuteException;
import com.zxmr.navigate.Executor;
import com.zxmr.util.ResourceManager;

public class OpportunityTask extends Executor {

	enum method{
		add,
		query,
		
	}
	@Override
	public void execute(Request request, Response response) {
		// TODO Auto-generated method stub
		method method = Enum.valueOf(method.class, this.getElement().getMethod());
		
		try
		{
			switch(method)
			{
			case add:
				add(request,response);
				break;
			case query:
				query(request,response);
				break;
			}
		}catch(Exception e)
		{
			ResponsePayload payload = new ResponsePayload();
			if(e instanceof ExecuteException)
			{
				payload.setValue(e.getMessage());
			}else
			{
				e.printStackTrace();
				payload.setValue("internal error");
			}
			response.setPayload(payload);
			response.setResult(ResultCode.COMPONENT_ERROR);
		}
	}
	
	private void add(Request request,Response response)throws ExecuteException
	{
		// check if has such authorization if yes forward the request to Utility component
		
		Task task = parseAdd(request);
		checkAddAuth(task,request.getAccount());
		
		System.out.println("authorization check successfully");
		
		request.getPayload().setUrl("/task/add");
		request.setInternal(true);
		try {
			request.send(request.getRequestProperties().getReplyTo(), "zxmr.utility");
		} catch (IOException e) {
			throw new ExecuteException("internal error");
		}
		request.setNeedResponse(false);
	}
	private void checkAddAuth(Task task,User user)throws ExecuteException
	{
		if(task.getRelate() != RelateType.opportunity)
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		
		OpportunityService service = new OpportunityService();
		Opportunity opp = service.queryOpportunity(task.getRelateID());
		
		if(opp == null || opp.getCompany() != user.getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth"));
		
		if(!opp.getOwner().equals(user.getName()) && user.getAccountType() != AccountType.Supervisor)
		{
			if(!this.isAuthorized(user.getId(), "addOppTaskOthers"))
			{
				throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.addOppTaskOthers")); 
			}
		}
	}
	private Task parseAdd(Request request)throws ExecuteException
	{
		try
		{
			return JSON.parseObject(request.getRequestParameters().get("parameters"), Task.class);
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		}
	}
	private void checkOpportunity(Opportunity opp, User user)throws ExecuteException
	{
		if(opp == null || opp.getCompany() != user.getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth"));
	}
	private void query(Request request,Response response)throws ExecuteException
	{
		System.out.println("query authorization check successfully");
		
		long id = 0;
		try
		{
			id = Long.parseLong(request.getRequestParameters().get("opp"));
		}catch(Exception e)
		{
			throw new ExecuteException("invalid parameter");
		}
		
		OpportunityService service = new OpportunityService();
		Opportunity opp = service.queryOpportunity(id);
		
		checkOpportunity(opp,request.getAccount());
		checkQueryAuth(opp,request.getAccount());
		
		// construct search bean
		TaskSearchBean searchBean = new TaskSearchBean();
		searchBean.setCompany(request.getAccount().getCompany());
		searchBean.setRelate(RelateType.opportunity.toString());
		if(id <= 0)
			throw new ExecuteException("invalid parameter");
		
		searchBean.setRelateID(id);
		

		// construct request payload
		RequestPayload payload = new RequestPayload();
		payload.setUrl("/task/query");
		Map<String,String> para = new HashMap<String,String>();
		para.put("p", JSON.toJSONString(searchBean));
		payload.setParameters(para);
		
		request.setPayload(payload);

		this.redirect(request, "zxmr.utility");
	}
	private void checkQueryAuth(Opportunity opp,User user)throws ExecuteException
	{
		if(!opp.getOwner().equals(user.getName()) && user.getAccountType() != AccountType.Supervisor)
		{
			if(!this.isAuthorized(user.getId(), "queryOppTaskOthers"))
			{
				throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.queryOppTaskOthers")); 
			}
		}
	}
}
